package com.chuangjiangx.member.basic.web.redis.keyspaceevents;


import com.chuangjiangx.member.coupon.ddd.application.MbrCouponApplication;
import com.chuangjiangx.member.common.utils.MbrKeyManager;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;

import java.io.Serializable;

/**
 * @author cj-ch
 * @date 2018/10/22 下午6:18
 * 会员卡券冻结过期
 */
@Slf4j
@Component
public class RedisKeyExpireEvent implements InitializingBean {

    @Autowired
    private MbrCouponApplication mbrCouponApplication;
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private RedisMessageListenerContainer redisMessageListenerContainer;
    @Autowired
    private RedisTemplate redisTemplate;

    public void handleMessage(Serializable message) {
        String msg = (String) message;
        if(StringUtils.isBlank(msg)){
            return;
        }
        if(msg.startsWith(MbrKeyManager.MBR_COUPON_LOCK_KEY)){
            // 锁定的卡券key到期
            // 自动解冻
            String code = msg.substring(MbrKeyManager.MBR_COUPON_LOCK_KEY.length());
            log.info("自动解冻卡券:{}",code);
            mbrCouponApplication.unlockMbrHasCoupon(code);
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {

        // 需要开启,执行命令 redis-cli config set notify-keyspace-events Ex
        Object execute = redisTemplate.execute(new RedisCallback() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                return connection.getNativeConnection();
            }
        });

        if(execute instanceof Jedis){
            Jedis jedis = (Jedis) execute;
            String ex = jedis.configSet("notify-keyspace-events", "Ex");
            if("OK".equals(ex)){
                log.info("####################################配置redis键过期事件########################");
                // 监听数据库0的Key过期事件
                MessageListenerAdapter messageListenerAdapter = new MessageListenerAdapter(this);
                messageListenerAdapter.afterPropertiesSet();
                redisMessageListenerContainer.addMessageListener(
                        messageListenerAdapter,
                        new ChannelTopic("__keyevent@0__:expired")
                );
            }else{
                log.warn("#########config set notify-keyspace-events Ex命令执行失败:{},将无法自动解冻卡券",ex);
            }
        }
    }
}
